package cn.csg.iotplatform.module.system.service.userproject;

import cn.csg.iotplatform.framework.common.util.object.BeanUtils;
import cn.csg.iotplatform.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csg.iotplatform.framework.web.core.util.WebFrameworkUtils;
import cn.csg.iotplatform.module.system.api.user.AdminUserApi;
import cn.csg.iotplatform.module.system.controller.admin.userproject.vo.ProjectVO;
import cn.csg.iotplatform.module.system.controller.admin.userproject.vo.UserProjectRespVO;
import cn.csg.iotplatform.module.system.controller.admin.userproject.vo.UserProjectSaveReqVO;
import cn.csg.iotplatform.module.system.dal.dataobject.projectcopy.ProjectDO;
import cn.csg.iotplatform.module.system.dal.dataobject.user.AdminUserDO;
import cn.csg.iotplatform.module.system.dal.dataobject.userproject.UserProjectDO;
import cn.csg.iotplatform.module.system.dal.mysql.projectcopy.ProjectMapper;
import cn.csg.iotplatform.module.system.dal.mysql.userproject.UserProjectMapper;
import cn.csg.iotplatform.module.system.service.project.ProjectService;
import cn.csg.iotplatform.module.system.service.user.AdminUserService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.csg.iotplatform.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csg.iotplatform.module.system.enums.ErrorCodeConstants.USER_AUTH_TARGET_USER_NOT_EXISTS;

/**
 * 用户&项目设备授权关系 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class UserProjectServiceImpl implements UserProjectService {

    @Resource
    private UserProjectMapper userProjectMapper;
    @Resource
    private AdminUserService userService;
    @Resource
    private ProjectMapper projectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUserProject(UserProjectSaveReqVO createReqVO) {
        if(userService.getUser(createReqVO.getUserId()) == null) throw exception(USER_AUTH_TARGET_USER_NOT_EXISTS);
        userProjectMapper.delete(UserProjectDO::getUserId,createReqVO.getUserId());
        List<UserProjectDO> list = Lists.newArrayList();
        for(String projectId : createReqVO.getProjectIds()){
            UserProjectDO userProject = UserProjectDO.builder().userId(createReqVO.getUserId()).projectId(projectId).build();
            list.add(userProject);
        }
        userProjectMapper.insertBatch(list,1000);
    }


    @Override
    public UserProjectRespVO getUserProject(Long userId) {
        List<ProjectVO> belongProjects;
        if(userService.isAdmin()){
            LambdaQueryWrapperX<ProjectDO> queryWrapper = new LambdaQueryWrapperX<>();
            queryWrapper.eq(ProjectDO::getEnablingStatus,1);
            queryWrapper.eq(ProjectDO::getDeleted,0);
            List<ProjectDO> list = projectMapper.selectList(queryWrapper);
            belongProjects = Lists.newArrayList();
            for(ProjectDO projectDO : list){
                belongProjects.add(ProjectVO.builder().projectId(projectDO.getId())
                        .projectName(projectDO.getProjectName())
                        .unitUser(projectDO.getUnitUser()).unitName(projectDO.getUnitName()).build());
            }
        }else{
            belongProjects = userProjectMapper.getBelongsProjects(WebFrameworkUtils.getLoginUserId());
        }
        Map<String,ProjectVO> belongsMap = belongProjects.stream().collect(Collectors.toMap(ProjectVO::getProjectId, Function.identity()));
        List<ProjectVO> targetBelongProjects = userProjectMapper.getBelongsProjects(userId);
        List<ProjectVO> unAuthProjects = Lists.newArrayList();
        for(ProjectVO vo : targetBelongProjects){
            if(belongsMap.containsKey(vo.getProjectId())) unAuthProjects.add(vo);
            if(unAuthProjects.size() == belongProjects.size()) break;
        }
        List<ProjectVO> authProjects = userProjectMapper.getAuthProjects(userId);
        return UserProjectRespVO.builder().unAuthProjects((List<ProjectVO>) CollectionUtil.subtract(unAuthProjects,authProjects)).authProjects(authProjects).build();
    }

}